﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;

namespace Xceed.Silverlight.Data
{
  internal abstract class QueryableHandler : SourceHandlerBase, IAsyncHandler
  {

    protected QueryableHandler( IQueryable dataSource )
    {
      if( dataSource == null )
        throw new ArgumentNullException( "dataSource" );
      this.m_dataSource = dataSource;
    }

    public IQueryable QueryableSource
    {
      get
      {
        return m_dataSource;
      }
    }

    public abstract ValueSource ItemCountSource
    {
      get;
    }

    public abstract bool IsFullySynchronized
    {
      get;
    }

    internal abstract void AddItemCountHint( int value, bool isMaximumValue );

    public abstract IAsyncResult BeginGetItemCount( AsyncCallback userCallback, object asyncState );

    public abstract GetCountResult EndGetItemCount( IAsyncResult getCountAsyncResult );

    private IQueryable m_dataSource;

    protected class ApproximateCountManager
    {
      public int ApproximateCount
      {
        get
        {
          return m_actualApproximateItemCount;
        }
      }

      public bool AddItemCountHint( int value, bool isMaximumValue )
      {
        if( isMaximumValue )
        {
          m_maxItemCount = Math.Min( value, m_maxItemCount );
          System.Diagnostics.Debug.Assert( m_minItemCount <= m_maxItemCount, "Previous info was non consistent" );
        }
        else
        {
          m_minItemCount = Math.Max( value, m_minItemCount );
          System.Diagnostics.Debug.Assert( m_minItemCount <= m_maxItemCount, "Previous info was non consistent" );
        }

        int newValue = m_actualApproximateItemCount;
        while( newValue < m_minItemCount )
        {
          newValue = newValue * 2;
        }
        newValue = Math.Min( newValue, m_maxItemCount );
        if( newValue != m_actualApproximateItemCount )
        {
          m_actualApproximateItemCount = newValue;
          return true;
        }
        return false;
      }

      private int m_minItemCount = 0;
      private int m_maxItemCount = int.MaxValue;
      private int m_actualApproximateItemCount = 1000;
    }
  }
}
